package chances.webui.taglibs;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@SuppressWarnings("serial")
public abstract class WebUITag extends BodyTagSupport {
	private String vm;
	protected VelocityEngine velocityEngine;
	protected String styleClass = null;
	protected String id = null;
	protected String name = null;
	protected String label = null;
	protected String style = null;

	public final static ObjectMapper objectMapper = new ObjectMapper();

	@Override
	public int doEndTag() throws JspException {
		this.apply();

		return super.doEndTag();
	}

	@Override
	public void release() {
		super.release();
		this.vm = null;
	}

	public String getJson(Object obj) {
		try {
			return objectMapper.writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return "{}";
	}

	protected abstract void initContext(Map<String, Object> context);

	protected void reset() {
		this.styleClass = null;
		this.name = null;
		this.id = null;
		this.label = null;
		this.style = null;
	}

	public void apply() {
		Map<String, Object> context = new HashMap<String, Object>();

		if (this.bodyContent != null) {
			context.put("bodyContent", this.getBodyContent());
		}
		context.put("request", pageContext.getRequest());
		vm = this.getClass().getSimpleName().replaceAll("(.*)Tag", "$1").toLowerCase();
		context.put("tag", this);
		this.initContext(context);
		Template template = velocityEngine.getTemplate("webui/" + vm + ".vm");
		VelocityContext velocityContext = new VelocityContext();
		for (Entry<String, Object> entry : context.entrySet()) {
			velocityContext.put(entry.getKey(), entry.getValue());
		}
		template.merge(velocityContext, pageContext.getOut());
	}

	@Override
	public void setPageContext(PageContext pageContext) {
		super.setPageContext(pageContext);
		HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
		WebApplicationContext appContext = WebApplicationContextUtils
				.findWebApplicationContext(request.getServletContext());
		velocityEngine = appContext.getBean(VelocityEngine.class);
		this.reset();
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getStyleClass() {
		return styleClass;
	}

	public String getId() {
		return id;
	}

	public void setStyleClass(String styleClass) {
		this.styleClass = styleClass;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getLabel() {
		return label;
	}

	public void setLabel(String label) {
		this.label = label;
	}

	public String getStyle() {
		return style;
	}

	public void setStyle(String style) {
		this.style = style;
	}

}
